import Notification from "../models/notification.model.js"
import Putout from "../models/putout.model.js"
import User from "../models/user.model.js"
import { v2 as cloudinary } from "cloudinary"

export const createPutout = async (req, res) => {
    try {
        const { text } = req.body
        let { img } = req.body
        const userId = req.user._id.toString()

        const user = await User.findById(userId)
        if (!user) {
            return res.status(404).json({
                message: "User not found"
            })
        }

        if (!text && !img) {
            return res.status(404).json({
                error: "Putout mut be have text or image"
            })
        }

        if (img) {
            const uploadedResponse = await cloudinary.uploader.upload(img)
            img = uploadedResponse.secure_url
        }

        const newPutout = new Putout({
            user: userId,
            text,
            img,
        })

        await newPutout.save()
        res.status(201).json(newPutout)
    } catch (error) {
        console.log("Error in createPutout controller: ", error.message)
        res.status(500).json({
            error: "Internal Server Error"
        })
    }
}

export const deletePutout = async (req, res) => {
    try {
        const putout = await Putout.findById(req.params.id)
        if (!putout) {
            return res.staus(404).json({
                error: "the provided putout id not found"
            })
        }

        if (putout.user.toString() !== req.user._id.toString()) {
            return res.staus(401).json({
                error: "You are not authorized to delete this putout"
            })
        }

        if (putout.img) {
            const imgId = putout.img.split("/").pop().split(".")[0]
            // delete the putout img
            await cloudinary.uploader.destroy(imgId)
        }

        await Putout.findByIdAndDelete(req.params.id)

        res.status(200).json({
            message: "Putout deleted successfully"
        })
    } catch (error) {
        console.log("Error in deletePutout controller: ", error.message)
        return res.status(500).json({
            error: "Internal Sever Error"
        })
    }
}

export const commentOnPutout = async (req, res) => {
    try {
        const { text } = req.body
        const putoutId = req.params.id
        const userId = req.user._id

        if (!text) {
            return res.status(400).json({
                error: "comment text field is required"
            })
        }

        const putout = await Putout.findById(putoutId)

        if (!putout) {
            return res.status(404).json({
                error: "Putout not found"
            })
        }

        const commetn = { user: userId, text }

        putout.comment.push(comment)

        await putout.save()

        res.status(200).json(putout)
    } catch (error) {
        console.log("Error in commentOnPutout controller: ", error.message)
        res.status(500).json({
            error: "Internal Server Error"
        })
    }
}

export const likeUnlikePutout = async (req, res) => {
    try {
        const userId = req.user._id
        const { id: putoutId } = req.params

        const putout = await Putout.findById(putoutId)

        if (!putout) {
            return res.status(404).json({
                error: "Putout not found"
            })
        }

        const userLikedPutout = putout.likes.includes(userId)

        if (userLikedPutout) {
            // Unlike Putout
            await Putout.updateOne({ _id: putoutId }, { $pull: { likes: userId } })
            await User.updateOne({ _id: userId }, { $pull: { likedPutouts: putoutId } })

            const updatedLikes = putout.likes.filter((id) => id.toString() !== userId.toString())

            res.status(200).json(updatedLikes)
        } else {
            // Like Putout
            putout.likes.push(userId)
            await User.updateOne({ _id: userId }, { $push: { likedPutouts: putoutId } })
            await putout.save()

            const notification = new Notification({
                from: userId,
                to: putout.user,
                type: "like"
            })

            await notification.save()

            const updatedLikes = putout.likes

            res.status(200).json(updatedLikes)
        }
    } catch (error) {
        console.log("Error in likeUnlikePutout: ", error.message)
        res.status(500).json({
            error: "Internal Server Error"
        })
    }
}

export const getAllPutouts = async (req, res) => {
    try {
        // find all Putouts
        const putouts = await Putout.find()
            .sort({ createdAt: -1 })
            .populate({
                path: "user",
                select: "-password",
            })
            .populate({
                path: "comments.user",
                select: "-password",
            })

        if (putouts.length === 0) {
            return res.status(200).json([])
        }

        res.status(200).json(putouts)
    } catch (error) {
        console.log("Error in getAllPutouts controller: ", error.message)
        return res.status(500).json({
            error: "Internal Server Error"
        })
    }
}

export const getLikedPutouts = async (req, res) => {
    const userId = req.params.id

    try {
        const user = await User.findById(userId)
        if (!user) {
            return res.status(404).json({
                error: "User not found"
            })
        }

        const likedPutouts = await Putout.find({
            _id: { $in: user.likedPutouts }
        }).populate({
            path: "user",
            select: "-password",
        }).populate({
            path: "comments.user",
            select: "-password",
        })

        res.status(200).json(likedPutouts)
    } catch (error) {
        console.log("Error in getLikedPutouts controller: ", error.message)
        res.status(500).json({
            error: "Internal Server Error"
        })
    }
}

export const getFollowingPutouts = async (req, res) => {
    try {
        const userId = req.user._id
        const user = await User.findById(userId)
        if (!user) {
            res.status(404).json({
                error: "User not found"
            })
        }

        const following = user.following

        const feedPutouts = await Putout.find({
            user: { $in: following }
        }).sort({ createdAt: -1 })
            .populate({
                path: "user",
                select: "-password",
            })
            .populate({
                path: "comments.user",
                select: "-password",
            })

        res.status(200).json(feedPutouts)
    } catch (error) {
        console.log("Error in getFollowingPutouts controller: ", error.message)
        res.status(500).json({
            error: "Internal Server Error"
        })
    }
}

export const getUserPutouts = async (req, res) => {
    try {
        const { username } = req.params

        const user = await User.findOne({ username })
        if (!user) {
            return res.status(404).json({
                error: "User not found"
            })
        }

        const putouts = await Putout.find({ user: user._id })
            .sort({ createdAt: -1 })
            .populate({
                path: "user",
                select: "-password",
            })
            .populate({
                path: "comments.user",
                select: "-password",
            })

        res.status(200).json(putouts)
    } catch (error) {
        console.log("Error in getUserPutouts controller: ", error.message)
        res.status(500).json({
            error: "Internal Server Error"
        })
    }
}